package com.wxd.woff.table;

import com.wxd.woff.AbstractOTFDataStream;
import com.wxd.woff.AbstractWoffTable;
import com.wxd.woff.ByteBufferOTFDataStream;
import com.wxd.woff.WoffFont;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;

/**
 * Created with IntelliJ IDEA.
 *
 * @author: wangxindong
 * @date: 2018/9/2-09:19
 */
public class PostScriptTable extends AbstractWoffTable {

	public static final String TAG = "post";

	private int version;
	private int italicAngle;
	private short underlinePosition;
	private short underlineThickness;
	private int isFixedPitch;
	private int minMemType42;
	private int maxMemType42;
	private int mimMemType1;
	private int maxMemType1;
	private String[] glyphNames = null;

	public PostScriptTable(WoffFont woffFont) {
		super(woffFont);
	}

	@Override
	public void read(WoffFont woffFont, AbstractOTFDataStream stream) throws IOException {
		stream.seek(offset);
		byte[] fontData = stream.read(compLength);
		byte[] inflateFont = inflateFontData(fontData);
		AbstractOTFDataStream data = new ByteBufferOTFDataStream(inflateFont);

		version = data.readInt();
		italicAngle = data.readInt();
		underlinePosition = data.readSignedShort();
		underlineThickness = data.readSignedShort();
		isFixedPitch = data.readInt();
		minMemType42 = data.readInt();
		maxMemType42 = data.readInt();
		mimMemType1 = data.readInt();
		maxMemType1 = data.readInt();

		if (version == 0x00010000) {
			/*
			 * This TrueType font file contains exactly the 258 glyphs in the standard
			 * Macintosh TrueType.
			 */
			glyphNames = new String[WGL4Names.NUMBER_OF_MAC_GLYPHS];
			System.arraycopy(WGL4Names.MAC_GLYPH_NAMES, 0, glyphNames, 0, WGL4Names.NUMBER_OF_MAC_GLYPHS);
		} else if (version == 0x00020000) {
			int numGlyphs = data.readUnsignedShort();
			int[] glyphNameIndex = new int[numGlyphs];
			glyphNames = new String[numGlyphs];
			int maxIndex = Integer.MIN_VALUE;
			for (int i = 0; i < numGlyphs; i++) {
				int index = data.readUnsignedShort();
				glyphNameIndex[i] = index;
				// PDFBOX-808: Index numbers between 32768 and 65535 are
				// reserved for future use, so we should just ignore them
				if (index <= 32767) {
					maxIndex = Math.max(maxIndex, index);
				}
			}
			String[] nameArray = null;
			if (maxIndex >= WGL4Names.NUMBER_OF_MAC_GLYPHS) {
				nameArray = new String[maxIndex - WGL4Names.NUMBER_OF_MAC_GLYPHS + 1];
				for (int i = 0; i < maxIndex - WGL4Names.NUMBER_OF_MAC_GLYPHS + 1; i++) {
					int numberOfChars = data.readUnsignedByte();
					nameArray[i] = data.readString(numberOfChars);
				}
			}
			for (int i = 0; i < numGlyphs; i++) {
				int index = glyphNameIndex[i];
				if (index < WGL4Names.NUMBER_OF_MAC_GLYPHS) {
					glyphNames[i] = WGL4Names.MAC_GLYPH_NAMES[index];
				} else if (index >= WGL4Names.NUMBER_OF_MAC_GLYPHS && index <= 32767) {
					glyphNames[i] = nameArray[index - WGL4Names.NUMBER_OF_MAC_GLYPHS];
				} else {
					// PDFBOX-808: Index numbers between 32768 and 65535 are
					// reserved for future use, so we should just ignore them
					glyphNames[i] = ".undefined";
				}
			}
		} else if (version == 0x00025000) {
			int[] glyphNameIndex = new int[woffFont.getNumberOfGlyphs()];
			for (int i = 0; i < glyphNameIndex.length; i++) {
				int offset = data.readSignedByte();
				glyphNameIndex[i] = i + 1 + offset;
			}
			glyphNames = new String[glyphNameIndex.length];
			for (int i = 0; i < glyphNames.length; i++) {
				String name = WGL4Names.MAC_GLYPH_NAMES[glyphNameIndex[i]];
				if (name != null) {
					glyphNames[i] = name;
				}
			}

		} else if (version == 0x00030000) {
			LOGGER.debug("No PostScript name information is provided for the font " + woffFont);
		}
	}

	public int getVersion() {
		return version;
	}

	public void setVersion(int version) {
		this.version = version;
	}

	public int getItalicAngle() {
		return italicAngle;
	}

	public void setItalicAngle(int italicAngle) {
		this.italicAngle = italicAngle;
	}

	public short getUnderlinePosition() {
		return underlinePosition;
	}

	public void setUnderlinePosition(short underlinePosition) {
		this.underlinePosition = underlinePosition;
	}

	public short getUnderlineThickness() {
		return underlineThickness;
	}

	public void setUnderlineThickness(short underlineThickness) {
		this.underlineThickness = underlineThickness;
	}

	public int getIsFixedPitch() {
		return isFixedPitch;
	}

	public void setIsFixedPitch(int isFixedPitch) {
		this.isFixedPitch = isFixedPitch;
	}

	public int getMinMemType42() {
		return minMemType42;
	}

	public void setMinMemType42(int minMemType42) {
		this.minMemType42 = minMemType42;
	}

	public int getMaxMemType42() {
		return maxMemType42;
	}

	public void setMaxMemType42(int maxMemType42) {
		this.maxMemType42 = maxMemType42;
	}

	public int getMimMemType1() {
		return mimMemType1;
	}

	public void setMimMemType1(int mimMemType1) {
		this.mimMemType1 = mimMemType1;
	}

	public int getMaxMemType1() {
		return maxMemType1;
	}

	public void setMaxMemType1(int maxMemType1) {
		this.maxMemType1 = maxMemType1;
	}

	public String[] getGlyphNames() {
		return glyphNames;
	}

	public void setGlyphNames(String[] glyphNames) {
		this.glyphNames = glyphNames;
	}

	@Override
	public String toString() {
		return "AbstractWoffTable{" + "tag='" + tag + '\'' + ", offset=" + offset + ", compLength=" + compLength
				+ ", origLength=" + origLength + ", origChecksum=" + origChecksum + ", version=" + version
				+ ", italicAngle=" + italicAngle + ", underlinePosition=" + underlinePosition + ", underlineThickness="
				+ underlineThickness + ", isFixedPitch=" + isFixedPitch + ", minMemType42=" + minMemType42
				+ ", maxMemType42=" + maxMemType42 + ", mimMemType1=" + mimMemType1 + ", maxMemType1=" + maxMemType1
				+ ", glyphNames=" + Arrays.toString(glyphNames) + '}';
	}
}
